package org.mybatis.generator.plugins.fx.elements;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.xml.TextElement;
import util.IdUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * cjianquan 2019/8/4
 */
public class FxMethodGenerator {
    private IntrospectedTable introspectedTable;


    private String tableName;

    private String tableLab;

    private String prePack;
    private String moduleName;

    private String prePackPath;



    public FxMethodGenerator(IntrospectedTable introspectedTable,
                             String prePack,String moduleName,String prePath) {
        this.introspectedTable = introspectedTable;
        this.prePack = prePack;
        this.moduleName = moduleName;
        tableName = introspectedTable.getTableConfiguration().getTableName();
        tableName=toLowerCase(tableName);
        tableLab = introspectedTable.getRemarks();
        while (tableName.lastIndexOf("_") != -1) {
            int index = tableName.lastIndexOf("_");
            tableName = tableName.replaceFirst(
                    "_" + tableName.substring(index + 1, index + 2), tableName
                            .substring(index + 1, index + 2).toUpperCase());
        }

        this.prePackPath = prePath;
    }


    public TextElement getFxml(){
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
                .append("<?import javafx.geometry.Insets?>\n")
                .append("<?import javafx.scene.control.*?>\n")
                .append("<?import javafx.scene.control.cell.*?>\n")
                .append("<?import javafx.scene.layout.*?>\n")
                .append("<AnchorPane prefHeight=\"483.0\" prefWidth=\"768.0\" xmlns=\"http://javafx.com/javafx/8.0.111\" xmlns:fx=\"http://javafx.com/fxml/1\"\n")
                .append("\t\tfx:controller=\""+prePack+".view.controller."+moduleName+"."+toUpperCase(tableName)+"Controller\">\n");
        sb.append("\t<children>\n")
                .append("\t\t<BorderPane layoutX=\"14.0\" layoutY=\"7.0\" AnchorPane.bottomAnchor=\"5.0\" AnchorPane.leftAnchor=\"5.0\" AnchorPane.rightAnchor=\"5.0\" AnchorPane.topAnchor=\"5.0\">\n")
                .append("\t\t\t<top>\n")
                .append("\t\t\t\t<TitledPane text=\"条件过滤\" expanded=\"false\">\n")
                .append("\t\t\t\t\t<FlowPane alignment=\"CENTER_LEFT\"  BorderPane.alignment=\"CENTER_LEFT\" vgap=\"3\" hgap=\"5\">\n")
                .append("\t\t\t\t\t\t<children>\n");

        List<IntrospectedColumn> columns = introspectedTable.getBaseColumns();
        StringBuilder searchSb = new StringBuilder();
        StringBuilder colSb = new StringBuilder();
        for (IntrospectedColumn column : columns) {
            if (!column.getJavaProperty().equals("id")) {
                searchSb.append("\t\t\t\t\t\t\t<Label text=\""+column.getRemarks()+"：\" />\n");
                FullyQualifiedJavaType fqjt = column.getFullyQualifiedJavaType();

                if(fqjt.getShortName().equals("Integer") || fqjt.getShortName().equals("Boolean")){
                    searchSb.append("\t\t\t\t\t\t\t<ComboBox fx:id=\""+column.getJavaProperty()+"Field\"/>\n");
                }else if(fqjt.getShortName().equals("Date")){
                    searchSb.append("\t\t\t\t\t\t\t<DatePicker fx:id=\""+column.getJavaProperty()+"StartField\" prefWidth=\"140\"/>\n")
                            .append("\t\t\t\t\t\t\t<Label text=\"--\" />\n")
                            .append("\t\t\t\t\t\t\t<DatePicker fx:id=\""+column.getJavaProperty()+"EndField\" prefWidth=\"140\"/>\n");
                }else{
                    searchSb.append("\t\t\t\t\t\t\t<TextField fx:id=\""+column.getJavaProperty()+"Field\" />\n");
                }
                colSb.append("\t\t\t\t\t\t\t\t<TableColumn fx:id=\""+column.getJavaProperty()+"Col\" minWidth=\"40.0\" text=\""+column.getRemarks()+"\" >\n")
                        .append("\t\t\t\t\t\t\t\t\t<cellValueFactory>\n")
                        .append("\t\t\t\t\t\t\t\t\t\t<PropertyValueFactory property=\""+column.getJavaProperty()+"\"/>\n")
                        .append("\t\t\t\t\t\t\t\t\t</cellValueFactory>\n")
                        .append("\t\t\t\t\t\t\t\t</TableColumn>\n");
            }else{
                colSb.append("\t\t\t\t\t\t\t\t<TableColumn fx:id=\"idCol\" minWidth=\"40.0\" text=\"Id\" visible=\"false\" >\n")
                        .append("\t\t\t\t\t\t\t\t\t<cellValueFactory>\n")
                        .append("\t\t\t\t\t\t\t\t\t\t<PropertyValueFactory property=\"id\"/>\n")
                        .append("\t\t\t\t\t\t\t\t\t</cellValueFactory>\n")
                        .append("\t\t\t\t\t\t\t\t</TableColumn>\n");
            }
        }

        sb.append(searchSb.toString());


        sb.append("\t\t\t\t\t\t\t<Button fx:id=\"searchBtn\" mnemonicParsing=\"false\" onAction=\"#searchAction\" text=\"查询\" />\n")
                .append("\t\t\t\t\t\t\t<Button fx:id=\"resetBtn\" mnemonicParsing=\"false\" onAction=\"#resetAction\" text=\"清空\" />\n")
                .append("\t\t\t\t\t\t</children>\n")
                .append("\t\t\t\t\t\t<opaqueInsets>\n")
                .append("\t\t\t\t\t\t\t<Insets />\n")
                .append("\t\t\t\t\t\t</opaqueInsets>\n")
                .append("\t\t\t\t\t\t<BorderPane.margin>\n")
                .append("\t\t\t\t\t\t\t<Insets />\n")
                .append("\t\t\t\t\t\t</BorderPane.margin>\n")
                .append("\t\t\t\t\t</FlowPane>\n")
                .append("\t\t\t\t</TitledPane>\n")
                .append("\t\t\t</top>\n")
                .append("\t\t\t<center>\n")
                .append("\t\t\t\t<Pagination fx:id=\"paginationPn\" layoutX=\"1.0\" layoutY=\"-5.0\" maxPageIndicatorCount=\"15\" pageCount=\"5\" prefHeight=\"470.0\" prefWidth=\"785.0\">\n")
                .append("\t\t\t\t\t<fx:define>\n")
                .append("\t\t\t\t\t\t<TableView fx:id=\""+tableName+"TableView\" editable=\"true\" prefHeight=\"314.0\" prefWidth=\"759.0\" tableMenuButtonVisible=\"true\" BorderPane.alignment=\"CENTER\">\n")
                .append("\t\t\t\t\t\t\t<columns>\n")
                .append("\t\t\t\t\t\t\t\t<TableColumn fx:id=\"col_number\" minWidth=\"40\" maxWidth=\"40\" text=\"序号\" sortable=\"false\"/>\n")
                .append(colSb.toString())
                .append("\t\t\t\t\t\t\t</columns>\n")
                .append("\t\t\t\t\t\t\t<BorderPane.margin>\n")
                .append("\t\t\t\t\t\t\t\t<Insets bottom=\"5.0\" top=\"5.0\" />\n")
                .append("\t\t\t\t\t\t\t</BorderPane.margin>\n")
                .append("\t\t\t\t\t\t\t<columnResizePolicy>\n")
                .append("\t\t\t\t\t\t\t\t<TableView fx:constant=\"CONSTRAINED_RESIZE_POLICY\" />\n")
                .append("\t\t\t\t\t\t\t</columnResizePolicy>\n")
                .append("\t\t\t\t\t\t</TableView>\n")
                .append("\t\t\t\t\t</fx:define>\n")
                .append("\t\t\t\t</Pagination>\n")
                .append("\t\t\t</center>\n")
                .append("\t\t</BorderPane>\n")
                .append("\t</children>\n");
        sb.append("</AnchorPane>\n");


        return new TextElement(sb.toString());
    }

    public TextElement getFxmlView(){
        StringBuilder sb = new StringBuilder();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String now = sdf.format(new Date());
        sb.append("package "+prePack+".fxmlView."+moduleName+";\n")
                .append("import de.felixroske.jfxsupport.AbstractFxmlView;\n")
                .append("import de.felixroske.jfxsupport.FXMLView;\n")
                .append("import org.springframework.context.annotation.Lazy;\n")
                .append("import org.springframework.context.annotation.Scope;\n")
                .append("/**\n")
                .append(" * cjianquan "+now+"\n")
                .append(" */\n")
                .append("@Scope(\"prototype\")\n")
                .append("@Lazy\n")
                .append("@FXMLView(value = \"/"+prePackPath+"/fxmlView/"+moduleName+"/"+toUpperCase(tableName)+".fxml\")\n")
                .append("public class "+toUpperCase(tableName)+"FxmlView extends AbstractFxmlView {\n")
                .append("}\n")
                .append("\n");

        return new TextElement(sb.toString());
    }

    public TextElement getView(){
        StringBuilder sb = new StringBuilder();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String now = sdf.format(new Date());
        sb.append("package "+prePack+".view."+moduleName+";\n")
                .append("import "+prePack+".model.po."+moduleName+"."+toUpperCase(tableName)+"Po;\n")
                .append("import "+prePack+".view.utils.DictUtils;\n")
                .append("import javafx.fxml.FXML;\n")
                .append("import javafx.fxml.Initializable;\n")
                .append("import javafx.scene.control.*;\n")
                .append("import lombok.Getter;\n")
                .append("import lombok.Setter;\n")
                .append("import java.util.Date;\n")
                .append("/**\n")
                .append(" * cjianquan "+now+"\n")
                .append(" */\n")
                .append("@Getter\n")
                .append("@Setter\n")
                .append("public abstract class "+toUpperCase(tableName)+"View implements Initializable {\n")
                .append("\t@FXML\n")
                .append("\tprotected TableView<"+toUpperCase(tableName)+"Po> "+tableName+"TableView;\n")
                .append("\t@FXML\n")
                .append("\tprotected Button searchBtn;\n")
                .append("\t@FXML\n")
                .append("\tprotected Button resetBtn;\n")
                .append("\t@FXML\n")
                .append("\tprotected Pagination paginationPn;\n");

        List<IntrospectedColumn> columns = introspectedTable.getBaseColumns();
        StringBuilder searchSb = new StringBuilder();
        StringBuilder colSb = new StringBuilder();
        for (IntrospectedColumn column : columns) {

            if (!column.getJavaProperty().equals("id")) {
                FullyQualifiedJavaType fqjt = column.getFullyQualifiedJavaType();
                searchSb.append("\t//搜索字段："+column.getRemarks()+"\n")
                        .append("\t@FXML\n");
                if(fqjt.getShortName().equals("Integer")){
                    searchSb.append("\tprotected ComboBox<DictUtils.DictBean> "+column.getJavaProperty()+"Field;\n");
                    colSb.append("\t//列表字段："+column.getRemarks()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,Integer> "+column.getJavaProperty()+"Col;\n");
                }else if(fqjt.getShortName().equals("Boolean")){
                    searchSb.append("\tprotected ComboBox<DictUtils.DictBean> "+column.getJavaProperty()+"Field;\n");
                    colSb.append("\t//列表字段："+column.getRemarks()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,Boolean> "+column.getJavaProperty()+"Col;\n");
                }else if(fqjt.getShortName().equals("Long")){
                    colSb.append("\t//列表字段："+column.getRemarks()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,Long> "+column.getJavaProperty()+"Col;\n");
                    searchSb.append("\tprotected TextField "+column.getJavaProperty()+"Field;\n");
                }else if(fqjt.getShortName().equals("Double")){
                    colSb.append("\t//列表字段："+column.getRemarks()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,Double> "+column.getJavaProperty()+"Col;\n");
                    searchSb.append("\tprotected TextField "+column.getJavaProperty()+"Field;\n");
                }else if(fqjt.getShortName().equals("Float")){
                    colSb.append("//列表字段："+column.getRemarks()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,Float> "+column.getJavaProperty()+"Col;\n");
                    searchSb.append("\tprotected TextField "+column.getJavaProperty()+"Field;\n");
                }else if(fqjt.getShortName().equals("String")){
                    searchSb.append("\tprotected TextField "+column.getJavaProperty()+"Field;\n");
                    colSb.append("\t//列表字段："+column.getRemarks()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,String> "+column.getJavaProperty()+"Col;\n");
                }else if(fqjt.getShortName().equals("Date")){
                    searchSb.append("\tprotected DatePicker "+column.getJavaProperty()+"StartField;\n")
                            .append("\t@FXML\n")
                            .append("\tprotected DatePicker "+column.getJavaProperty()+"EndField;\n");
                    colSb.append("\t//列表字段："+column.getRemarks()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,Date> "+column.getJavaProperty()+"Col;\n");
                }else{
                    searchSb.append("\tprotected TextField "+column.getJavaProperty()+"Field;//else字段类型为："+fqjt.getShortName()+"\n");
                    colSb.append("\t//列表字段："+column.getRemarks()+",else字段类型为："+fqjt.getShortName()+"\n")
                            .append("\t@FXML\n")
                            .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,String> "+column.getJavaProperty()+"Col;\n");
                }
            }else{
                colSb.append("\t//列表字段："+column.getRemarks()+"\n")
                        .append("\t@FXML\n")
                        .append("\tprotected TableColumn<"+toUpperCase(tableName)+"Po,Long> "+column.getJavaProperty()+"Col;\n");
            }
        }

        sb.append(searchSb.toString())
                .append(colSb.toString())
                .append("\t@FXML\n" +
                        "\tprotected TableColumn col_number;\n")
                .append("}\n");
        return new TextElement(sb.toString());
    }

    public TextElement getController(){
        StringBuilder sb = new StringBuilder();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String now = sdf.format(new Date());

        List<IntrospectedColumn> columns = introspectedTable.getBaseColumns();
        StringBuilder searchSb = new StringBuilder();
        StringBuilder colSb = new StringBuilder();
        StringBuilder menuItemSb = new StringBuilder();
        int menuCnt = 0;
        StringBuilder dialogFieldSb = new StringBuilder();
        StringBuilder setFieldSb = new StringBuilder();
        StringBuilder gridSb = new StringBuilder();
        int columnIndex = 0,rowIndex = 0;
        StringBuilder listSb = new StringBuilder();
        StringBuilder resetSb = new StringBuilder();
        for (IntrospectedColumn column : columns) {
            if(menuCnt<3){
                menuItemSb.append("                MenuItem "+column.getJavaProperty()+"Menu = new MenuItem(\""+column.getRemarks()+"\");\n")
                        .append("                "+column.getJavaProperty()+"Menu.setOnAction(event1 -> {\n" +
                                "                    "+toUpperCase(tableName)+"Po selPo = "+tableName+"TableView.getSelectionModel().getSelectedItem();\n" +
                                "                    ComUtils.setClipContent(\"\"+selPo.get"+toUpperCase(column.getJavaProperty())+"());\n" +
                                "                });\n");
                menuItemSb.append("                copyMenu.getItems().add("+column.getJavaProperty()+"Menu);\n");
                menuCnt++;
            }
            if (!column.getJavaProperty().equals("id")) {
                FullyQualifiedJavaType fqjt = column.getFullyQualifiedJavaType();

                if(fqjt.getShortName().equals("Integer") || fqjt.getShortName().equals("Boolean")){
                    searchSb.append("        "+column.getJavaProperty()+"Field.getItems().addAll(DictUtils.statusList);\n");
                    searchSb.append("        "+column.getJavaProperty()+"Field.setConverter(DictUtils.getConverter());\n");
                    colSb.append("        "+column.getJavaProperty()+"Col.setCellFactory(col->ComUtils.getTableCell(null,DictUtils.statusList));\n");
                    dialogFieldSb.append("        ChoiceBox<DictUtils.DictBean> "+column.getJavaProperty()+"Field = new ChoiceBox<>();\n" +
                            "        "+column.getJavaProperty()+"Field.getItems().addAll(DictUtils.statusList);\n" +
                            "        "+column.getJavaProperty()+"Field.setConverter(DictUtils.getConverter());\n" +
                            "        "+column.getJavaProperty()+"Field.valueProperty().addListener((observable,oldValue,newValue)->{\n" +
                            "            "+tableName+"Po.set"+toUpperCase(column.getJavaProperty())+"(newValue.toIntVal());\n" +
                            "        });\n");

                    setFieldSb.append("        "+column.getJavaProperty()+"Field.setValue(DictUtils.getBeanByVal(DictUtils.statusList,"+tableName+"Po.get"+toUpperCase(column.getJavaProperty())+"()));\n");
                    listSb.append("        qo.set"+toUpperCase(column.getJavaProperty())+"(ComUtils.getFieldVal("+column.getJavaProperty()+"Field));\n");
                    resetSb.append("        "+column.getJavaProperty()+"Field.setValue(null);\n");
                }else if(fqjt.getShortName().equals("Boolean")){
                }else if(fqjt.getShortName().equals("Long")){
                }else if(fqjt.getShortName().equals("Double")){
                }else if(fqjt.getShortName().equals("Float")){
                }else if(fqjt.getShortName().equals("String")){
                    dialogFieldSb.append("        TextField "+column.getJavaProperty()+"Field = new TextField();\n" +
                            "        "+column.getJavaProperty()+"Field.textProperty().addListener((observable,oldValue,newValue)->{\n" +
                            "            "+tableName+"Po.set"+toUpperCase(column.getJavaProperty())+"(newValue);\n" +
                            "        });\n");
                    setFieldSb.append("        "+column.getJavaProperty()+"Field.setText("+tableName+"Po.get"+toUpperCase(column.getJavaProperty())+"());\n");
                    listSb.append("        qo.set"+toUpperCase(column.getJavaProperty())+"("+column.getJavaProperty()+"Field.getText());\n");
                    resetSb.append("        "+column.getJavaProperty()+"Field.setText(null);\n");
                }else if(fqjt.getShortName().equals("Date")){
                    colSb.append("        "+column.getJavaProperty()+"Col.setCellFactory(col->ComUtils.getTableCell(DateUtils.DEFAULT_PATTERN,null));\n");
                    dialogFieldSb.append("        DatePicker "+column.getJavaProperty()+"Field = new DatePicker();\n" +
                            "        "+column.getJavaProperty()+"Field.valueProperty().addListener((observable,oldValue,newValue)->{\n" +
                            "            "+tableName+"Po.set"+toUpperCase(column.getJavaProperty())+"(DateUtils.parseLocalData(newValue));\n" +
                            "        });\n");
                    setFieldSb.append("        "+column.getJavaProperty()+"Field.setValue(DateUtils.toLocalDate("+tableName+"Po.get"+toUpperCase(column.getJavaProperty())+"()));\n");
                    listSb.append("        qo.set"+toUpperCase(column.getJavaProperty())+"Start(DateUtils.parseLocalData("+column.getJavaProperty()+"StartField.getValue()));\n" +
                            "        qo.set"+toUpperCase(column.getJavaProperty())+"End(DateUtils.parseLocalData("+column.getJavaProperty()+"EndField.getValue()));\n");
                    resetSb.append("        "+column.getJavaProperty()+"StartField.setValue(null);\n" +
                            "        "+column.getJavaProperty()+"EndField.setValue(null);\n");
                }else{
                    dialogFieldSb.append("        TextField "+column.getJavaProperty()+"Field = new TextField();\n" +
                            "        "+column.getJavaProperty()+"Field.textProperty().addListener((observable,oldValue,newValue)->{\n" +
                            "            "+tableName+"Po.set"+toUpperCase(column.getJavaProperty())+"(newValue);\n" +
                            "        });\n");
                    setFieldSb.append("        "+column.getJavaProperty()+"Field.setText(\"\"+"+tableName+"Po.get"+toUpperCase(column.getJavaProperty())+"());\n");
                    listSb.append("        qo.set"+toUpperCase(column.getJavaProperty())+"("+column.getJavaProperty()+"Field.getText());\n");
                    resetSb.append("        "+column.getJavaProperty()+"Field.setText(null);\n");
                }

                //columnIndex = 0,rowIndex = 0;
                gridSb.append("        grid.add(new Label(\""+column.getRemarks()+":\"), "+columnIndex+", "+rowIndex+");grid.add("+column.getJavaProperty()+"Field, "+(columnIndex+1)+", "+rowIndex+");\n");
                columnIndex=columnIndex+2;
                if(columnIndex==4){
                    columnIndex = 0;
                    rowIndex++;
                }
            }
        }

        sb.append("package "+prePack+".view.controller."+moduleName+";\n" +
                "\n" +
                "import com.github.miemiedev.mybatis.paginator.domain.PageList;\n" +
                "import com.github.miemiedev.mybatis.paginator.domain.Paginator;\n" +
                "import com.xwintop.xcore.util.javafx.AlertUtil;\n" +
                "import "+prePack+".model.po."+moduleName+"."+toUpperCase(tableName)+"Po;\n" +
                "import "+prePack+".model.qo."+moduleName+"."+toUpperCase(tableName)+"Qo;\n" +
                "import "+prePack+".utils.DateUtils;\n" +
                "import "+prePack+".view.service."+moduleName+"."+toUpperCase(tableName)+"Service;\n" +
                "import "+prePack+".view.utils.ComUtils;\n" +
                "import "+prePack+".view.utils.DictUtils;\n" +
                "import "+prePack+".view.view."+moduleName+"."+toUpperCase(tableName)+"View;\n" +
                "import "+prePack+".view.utils.XJavaFxSystemUtil;\n"+
                "import javafx.collections.FXCollections;\n" +
                "import javafx.collections.ObservableList;\n" +
                "import javafx.event.ActionEvent;\n" +
                "import javafx.fxml.FXML;\n" +
                "import javafx.geometry.Insets;\n" +
                "import javafx.scene.Node;\n" +
                "import javafx.scene.control.*;\n" +
                "import javafx.scene.input.MouseButton;\n" +
                "import javafx.scene.layout.GridPane;\n" +
                "import javafx.util.Pair;\n" +
                "import lombok.Getter;\n" +
                "import lombok.Setter;\n" +
                "import lombok.extern.slf4j.Slf4j;\n" +
                "import org.apache.commons.lang3.StringUtils;\n"+
                "\n" +
                "import java.net.URL;\n" +
                "import java.util.Optional;\n" +
                "import java.util.ResourceBundle;\n" +
                "\n" +
                "/**\n" +
                " * cjianquan "+now+"\n" +
                " */\n" +
                "@Slf4j\n" +
                "@Getter\n" +
                "@Setter\n" +
                "public class "+toUpperCase(tableName)+"Controller extends "+toUpperCase(tableName)+"View{\n")
                .append("\n" +
                        "    Integer enableQuery = 1;\n" +
                        "    Boolean first = true;\n" +
                        "    private String orderByClause = \"\";\n" +
                        "\n" +
                        "    "+toUpperCase(tableName)+"Service "+tableName+"Service = new "+toUpperCase(tableName)+"Service();\n" +
                        "\n" +
                        "    private ObservableList<"+toUpperCase(tableName)+"Po> "+tableName+"List = FXCollections.observableArrayList();\n")
                .append("\n" +
                        "    @Override\n" +
                        "    public void initialize(URL location, ResourceBundle resources) {\n" +
                        "        initView();\n" +
                        "        initEvent();\n" +
                        "    }\n")
                .append("\n")//initView start
                .append("    private void initView() {\n" +
                        "        "+tableName+"TableView.setSortPolicy(tv->{\n" +
                                "            try{\n" +
                                "                String sortType = tv.getSortOrder().get(0).getSortType().name();\n" +
                                "                String sortField = tv.getSortOrder().get(0).getId();\n" +
                                "                String dbField = sortField.replaceAll(\"Col\",\"\");\n" +
                                "                orderByClause = \" \"+dbField+\" \"+sortType.toLowerCase().replaceAll(\"ending\",\"\");\n" +
                                "                createPage(0);\n" +
                                "            }catch (Exception e){\n" +
                                "                orderByClause = \"\";\n" +
                                "                if(first!=true){\n" +
                                "                    createPage(0);\n" +
                                "                }\n" +
                                "                first = false;\n" +
                                "            }\n" +
                                "            return true;\n" +
                                "        });\n"+
                        "        paginationPn.setMaxPageIndicatorCount(10);\n" +
                        "        paginationPn.setPageFactory((Integer pageIndex)->createPage(pageIndex));\n" +
                        "\n" +
                                searchSb.toString()+
                        "\n" +
                                colSb.toString()+
                        "        col_number.setCellFactory(col->ComUtils.getNumberCell());\n"+
                        "    }\n")
                .append("\n")//initView end
                .append("\n")//initEvent start
                .append("    private void initEvent() {\n" +
                        "        "+tableName+"TableView.setOnMouseClicked(event -> {\n" +
                        "            if (event.getButton() == MouseButton.SECONDARY) {\n" +
                        "                "+toUpperCase(tableName)+"Po selPo = "+tableName+"TableView.getSelectionModel().getSelectedItem();\n"+
                        "                MenuItem addMenu = new MenuItem(\"添加\");\n" +
                        "                addMenu.setOnAction(event1 -> {\n" +
                        "                    open"+toUpperCase(tableName)+"Dialog(event1,new "+toUpperCase(tableName)+"Po());\n" +
                        "                });\n" +
                        "\n" +
                        "                MenuItem editMenu = new MenuItem(\"修改\");\n" +
                        "                editMenu.setOnAction(event1 -> {\n" +
                        "                    open"+toUpperCase(tableName)+"Dialog(event1,selPo);\n" +
                        "                });\n" +
                        "                MenuItem delMenu = new MenuItem(\"删除选中行\");\n" +
                        "                delMenu.setOnAction(event1 -> {\n" +
                        "                    Alert alertDialog = new Alert(Alert.AlertType.CONFIRMATION,\"确定删除？\",new ButtonType(\"取消\", ButtonBar.ButtonData.NO),\n" +
                        "                            new ButtonType(\"确定\", ButtonBar.ButtonData.YES));\n" +
                        "                    alertDialog.setTitle(\"确认\");\n" +
                        "                    Optional<ButtonType> btnType = alertDialog.showAndWait();\n" +
                        "                    if(btnType.get().getButtonData().equals(ButtonBar.ButtonData.YES)){\n" +
                        "                        int cnt = this."+tableName+"Service.deleteById(selPo.getId());\n" +
                        "                        if(cnt>0){\n" +
                        "                            AlertUtil.showInfoAlert(\"操作成功\");\n" +
                        "                            "+tableName+"List.remove("+tableName+"TableView.getSelectionModel().getSelectedItem());\n" +
                        "                        }else{\n" +
                        "                            AlertUtil.showErrorAlert(\"操作失败\");\n" +
                        "                        }\n" +
                        "                    }\n" +
                        "                });\n" +
                        "\n" +
                        "                Menu copyMenu = new Menu(\"复制\");\n\n" +
                        "                MenuItem recMenu = new MenuItem(\"记录\");\n" +
                        "                recMenu.setOnAction(event1 -> {\n" +
                        "                    "+toUpperCase(tableName)+"Po selPo = "+tableName+"TableView.getSelectionModel().getSelectedItem();\n" +
                        "                    ComUtils.setClipContent(selPo);\n" +
                        "                });\n" +
                        "                copyMenu.getItems().add(recMenu);\n"+
                                menuItemSb.toString()+
                        "\n" +
                        "                Map<String,MenuItem> itemMap = new HashMap<String,MenuItem>();\n" +
                        "                itemMap.put(\""+tableName+":add\",addMenu);\n" +
                        "                itemMap.put(\""+tableName+":edit\",editMenu);\n" +
                        "                itemMap.put(\""+tableName+":del\",delMenu);\n" +
                        "                List<MenuItem> notSelItemList = new ArrayList<MenuItem>();\n" +
                        "                List<MenuItem> allItemList = XJavaFxSystemUtil.buildContextMenu(itemMap);\n" +
                        "                if(allItemList.contains(addMenu)){\n" +
                        "                    notSelItemList.add(addMenu);\n" +
                        "                }\n" +
                        "                allItemList.add(copyMenu);\n" +
                        "                ContextMenu ctxMenu = new ContextMenu();\n" +
                        "                if(selPo==null){\n" +
                        "                    ctxMenu.getItems().setAll(notSelItemList);\n" +
                        "                }else{\n" +
                        "                    ctxMenu.getItems().setAll(allItemList);\n" +
                        "                }\n" +
                        "\n" +
                        "                "+tableName+"TableView.setContextMenu(ctxMenu);\n"+
                        "            }\n" +
                        "        });\n" +
                        "    }\n")
                .append("\n")//initEvent end
                .append("\n")//openXXXDialog start
                .append("    private void open"+toUpperCase(tableName)+"Dialog(ActionEvent actionEvent, "+toUpperCase(tableName)+"Po "+tableName+"Po){\n" +
                        "        Dialog<Pair<String, String>> dialog = new Dialog<>();\n" +
                        "        dialog.setTitle(\""+tableLab+"\");\n" +
                        "\n" +
                        "        ButtonType saveButtonType = new ButtonType(\"保存\", ButtonBar.ButtonData.OK_DONE);\n" +
                        "        dialog.getDialogPane().getButtonTypes().addAll(saveButtonType, ButtonType.CANCEL);\n" +
                        "\n" +
                        "        GridPane grid = new GridPane();\n" +
                        "        grid.setHgap(10);\n" +
                        "        grid.setVgap(10);\n" +
                        "        grid.setPadding(new Insets(20, 20, 10, 10));\n" +
                        "\n" +
                                dialogFieldSb.toString()+
                        "\n"+
                        "\n"+
                                setFieldSb.toString()+
                        "\n" +
                                gridSb.toString()+
                        "\n" +
                        "        Node saveButton = dialog.getDialogPane().lookupButton(saveButtonType);\n" +
                        "        saveButton.addEventFilter(ActionEvent.ACTION, event -> {\n" +
                        "            try{\n" +
                        "                int cnt = 0;\n" +
                        "                if("+tableName+"Po.getId()!=null){\n" +
                        "                    cnt = this."+tableName+"Service.updateById("+tableName+"Po);\n" +
                        "                }else{\n" +
                        "                    cnt = this."+tableName+"Service.insert("+tableName+"Po);\n" +
                        "                }\n" +
                        "                if(cnt>0){\n" +
                        "                    AlertUtil.showInfoAlert(\"操作成功\");\n" +
                        "                    query"+toUpperCase(tableName)+"List(1);\n" +
                        "                }else{\n" +
                        "                    event.consume();\n" +
                        "                    AlertUtil.showErrorAlert(\"操作失败\");\n" +
                        "                }\n" +
                        "            }catch (Exception e){\n" +
                        "                e.printStackTrace();\n" +
                        "                event.consume();\n" +
                        "            }\n" +
                        "        });\n" +
                        "\n" +
                        "        dialog.getDialogPane().setContent(grid);\n" +
                        "        Optional<Pair<String, String>> result = dialog.showAndWait();\n" +
                        "    }\n")
                .append("\n")//openXXXDialog end
                .append("\n")//queryList start
                .append("    private void query"+toUpperCase(tableName)+"List(int page){\n" +
                        "        enableQuery = 0;\n"+
                        "        "+toUpperCase(tableName)+"Qo qo = new "+toUpperCase(tableName)+"Qo();\n" +
                                listSb.toString()+
                        "        if(StringUtils.isNotEmpty(orderByClause)){\n" +
                        "            qo.setOrderByClause(orderByClause);\n" +
                        "        }\n"+
                        "        try{\n" +
                        "            PageList<"+toUpperCase(tableName)+"Po> list =(PageList<"+toUpperCase(tableName)+"Po>) "+tableName+"Service.query(qo);\n" +
                        "            Paginator paginator = list.getPaginator();\n" +
                        "            enableQuery = 0;\n" +
                        "            paginationPn.setPageCount((paginator.getTotalCount()/paginator.getLimit())+1);\n" +
                        "            departmentList.clear();\n"+
                        "            "+tableName+"List.addAll(list);\n" +
                        "            changeWatchVar();\n" +
                        "        }catch (Exception e){\n" +
                        "            e.printStackTrace();\n" +
                        "        }\n" +
                        "    }\n")
                .append("\n")//queryList end
                .append("\n")//createPage start
                .append("    private Node createPage(Integer cnt) {\n" +
                        "        departmentList.clear();\n"+
                        "        if(enableQuery==1){\n" +
                        "            query"+toUpperCase(tableName)+"List(cnt+1);\n" +
                        "        }\n" +
                        "        "+tableName+"TableView.setItems("+tableName+"List);\n" +
                        "        return "+tableName+"TableView;\n" +
                        "    }\n")
                .append("\n")//createPage end
                .append("\n")//searchAction start
                .append("    @FXML\n" +
                        "    private void searchAction(ActionEvent event) {\n" +
                        "        searchBtn.setDisable(true);\n"+
                        "        "+tableName+"List.clear();\n" +
                        "        createPage(0);\n" +
                        "        searchBtn.setDisable(false);\n"+
                        "    }\n")
                .append("\n")//searchAction end
                .append("\n")//resetAction start
                .append("    @FXML\n" +
                        "    private void resetAction(ActionEvent event) {\n" +
                        resetSb.toString()+
                        "        orderByClause = \"\";\n"+
                        "        "+tableName+"List.clear();\n" +
                        "        resetBtn.setDisable(true);\n"+
                        "        createPage(0);\n" +
                        "        resetBtn.setDisable(false);\n"+
                        "    }\n")
                .append("\n")//resetAction end
                .append("    public void changeWatchVar(){\n" +
                        "        Thread thread = new Thread(new Runnable() {\n" +
                        "            @Override\n" +
                        "            public void run() {\n" +
                        "                try{\n" +
                        "                    Thread.sleep(1000);\n" +
                        "                    enableQuery = 1;\n" +
                        "                }catch (Exception e){\n" +
                        "\n" +
                        "                }\n" +
                        "            }\n" +
                        "        });\n" +
                        "        thread.start();\n" +
                        "    }\n")
                .append("\n")
                .append("}\n");


        return new TextElement(sb.toString());
    }

    public TextElement getService() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String now = sdf.format(new Date());
        StringBuilder sb = new StringBuilder();
        sb.append("package "+prePack+".view.service."+moduleName+";\n" +
                "\n" +
                "import com.alibaba.fastjson.JSONObject;\n" +
                "\n" +
                "import "+prePack+".model.po."+moduleName+"."+toUpperCase(tableName)+"Po;\n" +
                "import "+prePack+".model.qo."+moduleName+"."+toUpperCase(tableName)+"Qo;\n" +
                "import "+prePack+".model.vo.BaseResp;\n" +
                "import "+prePack+".view.service.BaseService;\n" +
                "\n" +
                "import java.util.List;\n" +
                "\n" +
                "/**\n" +
                " * cjianquan "+now+"\n" +
                " */\n" +
                "public class "+toUpperCase(tableName)+"Service extends BaseService {\n" +
                "\n" +
                "    public Integer deleteById(Long id) {\n" +
                "        JSONObject params = new JSONObject();\n" +
                "        params.put(\"ids\",\"\"+id);\n" +
                "        BaseResp resp = post(\""+moduleName+"/"+tableName+"/deleteByBatch\",params);\n" +
                "        return resp.isSuccess()?1:0;\n" +
                "    }\n" +
                "\n" +
                "    public List<"+toUpperCase(tableName)+"Po> query("+toUpperCase(tableName)+"Qo qo) {\n" +
                "        BaseResp resp = getList(\""+moduleName+"/"+tableName+"/query\",qo,"+toUpperCase(tableName)+"Po.class);\n" +
                "        if(resp.isSuccess()){\n" +
                "            return (List<"+toUpperCase(tableName)+"Po>)resp.getData();\n" +
                "        }\n" +
                "        return null;\n" +
                "    }\n" +
                "\n" +
                "    public int updateById("+toUpperCase(tableName)+"Po "+tableName+"Po) {\n" +
                "        BaseResp resp = saveBean(\""+moduleName+"/"+tableName+"/modify\","+tableName+"Po);\n" +
                "        return resp.isSuccess()?1:0;\n" +
                "    }\n" +
                "\n" +
                "    public int insert("+toUpperCase(tableName)+"Po "+tableName+"Po) {\n" +
                "        BaseResp resp = saveBean(\""+moduleName+"/"+tableName+"/add\","+tableName+"Po);\n" +
                "        return resp.isSuccess()?1:0;\n" +
                "    }\n" +
                "}\n\n");

        return new TextElement(sb.toString());
    }


    protected String toLowerCase(String tableName) {
        StringBuilder sb = new StringBuilder(tableName);
        sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
        return sb.toString();
    }

    /**
     * BaseUsers to baseUsers
     *
     * @param tableName
     * @return
     */
    protected String toUpperCase(String tableName) {
        StringBuilder sb = new StringBuilder(tableName);
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        return sb.toString();
    }



}
